package com.cloudcross.ssp.base.web;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import javax.servlet.ServletContext;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.WebApplicationContext;

import com.cloudcross.ssp.common.utils.Assert;
import com.cloudcross.ssp.common.utils.DateUtil.DateFmts;
import com.cloudcross.ssp.common.utils.String2MapUtils;
import com.cloudcross.ssp.loader.AdvertiserLoader;
import com.cloudcross.ssp.model.Account;
import com.cloudcross.ssp.service.IAccountService;

/**
 * 简单控制器。
 *
 * @author wuqiang.du
 */
public abstract class SimpleController extends ApplicationObjectSupport implements InitializingBean {
    private static final String SUBCLAZZ_SUFFIX = "Controller";

    protected static final String WEB_LOCATOR = "com.cloudcross.ssp.web";

    public static final String OK = "ok";
    public static final String ERROR = "error";

    /**
     * 功能首页模板路径
     */
    protected String index;

    /**
     * @return 返回到<code>page</code>页。
     */
    public final String page(String page) {
        return index.concat("/").concat(page);
    }

    /**
     * 重定向到某个uri。
     *
     * @param uri
     * @return
     */
    public final String redirect(String uri) {
        return "redirect:" + uri;
    }

    /**
     * 请求转发到某个uri上。
     *
     * @param uri
     * @return
     */
    public final String forward(String uri) {
        return "forward:" + uri;
    }

    /**
     * 从spring上下文中找<code>beanId</code>对象。
     *
     * @param beanClazz 实例类型
     * @param beanId    实例spring中ID
     * @return 实例对象
     */
    public final <T> T getBean(Class<T> beanClazz, String beanId) {
        Assert.notNull(beanClazz, "beanClazz can't be null.");
        Assert.isTrue(StringUtils.isNotBlank(beanId), "beanId can't be empty.");
        return beanClazz.cast(getApplicationContext().getBean(beanId));
    }

    /**
     * 从spring上下文中找<code>beanClazz</code>类型的对象。
     *
     * @param beanClazz 实例类型
     * @return 实例对象
     */
    public final <T> T getBean(Class<T> beanClazz) {
        Assert.notNull(beanClazz, "beanClazz can't be null.");
        return getApplicationContext().getBean(beanClazz);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        Class<?> myClazz = this.getClass();
        String fileName = myClazz.getSimpleName();
        if (fileName.endsWith(SUBCLAZZ_SUFFIX)) {
            fileName = fileName.substring(0, fileName.length() - SUBCLAZZ_SUFFIX.length());
        }

        // camel case to mid-line one.
        fileName = fileName
                .replaceAll(String.format("%s|%s|%s", "(?<=[A-Z])(?=[A-Z][a-z])", "(?<=[^A-Z])(?=[A-Z])", "(?<=[A-Za-z])(?=[^A-Za-z])"), "-")
                .toLowerCase();

        String relativeLocator = myClazz.getPackage().getName().trim().replaceFirst(WEB_LOCATOR, StringUtils.EMPTY).replaceAll("\\.", "/");

        index = StringUtils.isBlank(relativeLocator) ? fileName : relativeLocator.concat("/").concat(fileName);
        logger.debug("Controller: " + myClazz + " index page url is :" + index);
    }

    /**
     * @return 当前登录用户
     * @see User
     */
    public Account getLoginUser() {
        if (StringUtils.isBlank(getLoginUsername())) {
            return null;
        }
        IAccountService userService = getBean(IAccountService.class);
        Account loginUser = userService.querySingleAccount(getLoginUsername());
        return loginUser;
    }

    /**
     * @return 当前登录用户名
     */
    public String getLoginUsername() {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            return ((UserDetails) principal).getUsername();
        } else {
            return principal.toString();
        }
    }

    public ServletContext getServletContext() {
        ApplicationContext ac = getApplicationContext();
        if (ac instanceof WebApplicationContext) {
            return ((WebApplicationContext) ac).getServletContext();
        }
        return null;
    }

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        logger.debug("to customize request parameter binding with PropertyEditors");
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat(DateFmts.YYYY_MM_DD), true));
    }

    protected void initPatermater(Map<String, Object> paramMap, Map<String, Object> condition) {
        // 当前登陆用户，需求方系统需要判断是代理商还是广告主，其他系统不用
        Account account = getLoginUser();
        // 只有需求方系统账号登陆才需要判断
        String advertiserId = null;
        String advertiserName = "全部广告主";

        if (null != paramMap.get("selectedadvertiserId") && !"".equals(paramMap.get("selectedadvertiserId"))
                && !"-1".equals(paramMap.get("selectedadvertiserId")) && !"0".equals(paramMap.get("selectedadvertiserId"))) {
            advertiserId = paramMap.get("selectedadvertiserId").toString();
            condition.putAll(String2MapUtils.modifyString2Map(advertiserId, "advertiserIdSet"));
            advertiserName = (String) paramMap.get("selectedadvertiserName");
        } else {
            if (account.getSysType() == 3) {
                if (account.getAgentId() > 0 && account.getAdvertiserId() > 0) {// 广告主
                    // 没选广告主，默认查询所有广告主
                    String ids = account.getAdvertiserId().toString();
                    condition.putAll(String2MapUtils.modifyString2Map(ids, "advertiserIdSet"));
                } else if (account.getAgentId() > 0 && account.getAdvertiserId() == 0) {// 代理商
                    // 没选广告主，默认查询所有广告主
                    String ids = AdvertiserLoader.getAgentIdAdvertiserIdMap(account.getAgentId());
                    condition.putAll(String2MapUtils.modifyString2Map(ids, "advertiserIdSet"));
                }
            }
        }
        paramMap.put("advertiserId", advertiserId);
        if (paramMap.containsKey("jumpway")) {
            try {
                advertiserName = new String(advertiserName.getBytes("ISO-8859-1"), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        paramMap.put("selectedadvertiserName", advertiserName);

        // 订单
        String orderId = null;
        String orderName = "全部订单";
        if (null != paramMap.get("selectedorderId") && !"".equals(paramMap.get("selectedorderId")) && !"-1".equals(paramMap.get("selectedorderId"))
                && !"0".equals(paramMap.get("selectedorderId"))) {
            orderId = paramMap.get("selectedorderId").toString();
            condition.putAll(String2MapUtils.modifyString2Map(orderId, "orderIdSet"));
            orderName = (String) paramMap.get("selectedorderName");
        }
        paramMap.put("orderId", orderId);
        if (paramMap.containsKey("jumpway")) {
            try {
                orderName = new String(orderName.getBytes("ISO-8859-1"), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        paramMap.put("selectedorderName", orderName);
        // 投放
        String adGroupId = null;
        String adGroupName = "全部策略";
        if (null != paramMap.get("selectedadGroupId") && !"".equals(paramMap.get("selectedadGroupId"))
                && !"-1".equals(paramMap.get("selectedadGroupId")) && !"0".equals(paramMap.get("selectedadGroupId"))) {
            adGroupId = paramMap.get("selectedadGroupId").toString();
            condition.putAll(String2MapUtils.modifyString2Map(adGroupId, "adGroupIdSet"));
            adGroupName = (String) paramMap.get("selectedadGroupName");
        }
        paramMap.put("adGroupId", adGroupId);
        paramMap.put("selectedadGroupName", adGroupName);

        // 日期
        // 判断日期是否为默认值昨天，日期格式与上面相统一，用 to 分割
        String startDate = null;
        String endDate = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (null == paramMap.get("dateRangePicker") || "".equals(paramMap.get("dateRangePicker"))) {
            startDate = endDate = sdf.format(new Date().getTime() - 24 * 60 * 60 * 1000);
        } else {
            String[] choosedDate = ((String) paramMap.get("dateRangePicker")).split("to");
            startDate = choosedDate[0].trim();
            endDate = choosedDate[1].trim();
        }
        condition.put("startDate", startDate);
        condition.put("endDate", endDate);
    }

    // 报表导出，转码
    protected void initPatermaterExcel(Map<String, Object> paramMap, Map<String, Object> condition) {
        Account account = getLoginUser();// 当前登陆用户，需求方系统需要判断是代理商还是广告主，其他系统不用

        // 只有需求方系统账号登陆才需要判断
        String advertiserId = null;
        String advertiserName = "全部广告主";

        if (null != paramMap.get("selectedadvertiserId") && !"".equals(paramMap.get("selectedadvertiserId"))
                && !"-1".equals(paramMap.get("selectedadvertiserId")) && !"0".equals(paramMap.get("selectedadvertiserId"))) {
            advertiserId = paramMap.get("selectedadvertiserId").toString();
            condition.putAll(String2MapUtils.modifyString2Map(advertiserId, "advertiserIdSet"));
            advertiserName = (String) paramMap.get("selectedadvertiserName");
        } else {
            if (account.getSysType() == 3) {
                if (account.getAgentId() > 0 && account.getAdvertiserId() > 0) {// 广告主
                    // 没选广告主，默认查询所有广告主
                    String ids = account.getAdvertiserId().toString();
                    condition.putAll(String2MapUtils.modifyString2Map(ids, "advertiserIdSet"));
                } else if (account.getAgentId() > 0 && account.getAdvertiserId() == 0) {// 代理商
                    // 没选广告主，默认查询所有广告主
                    String ids = AdvertiserLoader.getAgentIdAdvertiserIdMap(account.getAgentId());
                    condition.putAll(String2MapUtils.modifyString2Map(ids, "advertiserIdSet"));
                }
            }
        }
        try {
            advertiserName = new String(advertiserName.getBytes("ISO-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        paramMap.put("advertiserId", advertiserId);
        paramMap.put("selectedadvertiserName", advertiserName);

        // 订单
        String orderId = null;
        String orderName = "全部订单";
        if (null != paramMap.get("selectedorderId") && !"".equals(paramMap.get("selectedorderId")) && !"-1".equals(paramMap.get("selectedorderId"))
                && !"0".equals(paramMap.get("selectedorderId"))) {
            orderId = paramMap.get("selectedorderId").toString();
            condition.putAll(String2MapUtils.modifyString2Map(orderId, "orderIdSet"));
            orderName = (String) paramMap.get("selectedorderName");
            try {
                orderName = new String(orderName.getBytes("ISO-8859-1"), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }

        paramMap.put("orderId", orderId);
        paramMap.put("selectedorderName", orderName);

        // 投放
        String adGroupId = null;
        String adGroupName = "全部策略";
        if (null != paramMap.get("selectedadGroupId") && !"".equals(paramMap.get("selectedadGroupId"))
                && !"-1".equals(paramMap.get("selectedadGroupId")) && !"0".equals(paramMap.get("selectedadGroupId"))) {
            adGroupId = paramMap.get("selectedadGroupId").toString();
            condition.putAll(String2MapUtils.modifyString2Map(adGroupId, "adGroupIdSet"));
            adGroupName = (String) paramMap.get("selectedadGroupName");
            try {
                adGroupName = new String(adGroupName.getBytes("ISO-8859-1"), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        paramMap.put("adGroupId", adGroupId);
        paramMap.put("selectedadGroupName", adGroupName);

        // 日期
        // 判断日期是否为默认值昨天，日期格式与上面相统一，用 to 分割
        String startDate = null;
        String endDate = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (null == paramMap.get("dateRangePicker") || "".equals(paramMap.get("dateRangePicker"))) {
            startDate = endDate = sdf.format(new Date().getTime() - 24 * 60 * 60 * 1000);
        } else {
            String[] choosedDate = ((String) paramMap.get("dateRangePicker")).split("to");
            startDate = choosedDate[0].trim();
            endDate = choosedDate[1].trim();
        }
        condition.put("startDate", startDate);
        condition.put("endDate", endDate);
        paramMap.put("startDate", startDate);
        paramMap.put("endDate", endDate);
    }
}
